package hn.cch.common.service.impl;


import hn.cch.common.service.MailService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.MailSendException;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.mail.Address;
import javax.mail.SendFailedException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


@Component
public class MailServiceImpl implements MailService {

    private static final Logger logger = LoggerFactory.getLogger(MailServiceImpl.class);

    @Resource
    private JavaMailSenderImpl mailSender;


    @PostConstruct
    public void postConstruct() {
        initMailSender();
    }

    public void initMailSender() {
        mailSender.setHost("smtp.qq.com");
        mailSender.setPort(587);
        mailSender.setUsername("chench.1024@qq.com");
        mailSender.setPassword("gpdleqppifbkeacj");
        mailSender.setProtocol("smtp");
        mailSender.setDefaultEncoding("utf-8");
        logger.info("initMailSender");
    }


    /**
     * 发送邮件
     *
     * @param personal 昵称
     * @param to       收件人
     * @param cc       抄送
     * @param bcc      密抄
     * @param subject  主题
     * @param content  正文
     * @param fileList 附件列表
     * @throws Exception
     */
    public void sendMail(String personal, String[] to, String[] cc, String[] bcc, String subject, String content, List<File> fileList) throws Exception {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setFrom(Objects.requireNonNull(mailSender.getUsername()), personal);
        // 邮件接收人
        if (to != null) {
            helper.setTo(to);
            logger.debug("setTo length:{}", to.length);
        }
        // 邮件抄送
        if (cc != null) {
            helper.setCc(cc);
            logger.debug("setCc length:{}", cc.length);
        }
        // 邮件密抄,不显示
        if (bcc != null) {
            helper.setBcc(bcc);
            logger.debug("setBcc length:{}", bcc.length);
        }
        helper.setSubject(subject);
        helper.setText(content, true);
        // 附件
        if (Objects.nonNull(fileList)) {
            for (File file : fileList) {
                if (!file.exists()) { // 文件不存在跳过
                    continue;
                }
                helper.addAttachment(file.getName(), file);
                logger.debug("addAttachment:{}", file.getName());
            }
        }
        mailSender.send(message);
    }

    /**
     * 发送邮件，如果异常返回无效邮箱地址
     *
     * @param personal 昵称
     * @param to       收件人
     * @param cc       抄送
     * @param bcc      密抄
     * @param subject  主题
     * @param content  正文
     * @param fileList 附件列表
     * @return 异常邮箱地址
     * @throws Exception
     */
    public List<String> sendMailInvalidAddresses(String personal, String[] to, String[] cc, String[] bcc, String subject, String content, List<File> fileList) throws Exception {
        try {
            sendMail(personal, to, cc, bcc, subject, content, fileList);
        } catch (MailSendException mailSendException) {
            Exception[] exceptions = mailSendException.getMessageExceptions();
            for (Exception exception : exceptions) {
                if (exception instanceof SendFailedException) {
                    SendFailedException sendFailedException = (SendFailedException) exception;
                    // 异常收件人
                    Address[] invalidAddresses = sendFailedException.getInvalidAddresses();
                    return Arrays.stream(invalidAddresses).map(Address::toString).collect(Collectors.toList());
                } else {
                    throw exception;
                }
            }
        } catch (SendFailedException sendFailedException) {
            // 异常收件人
            Address[] invalidAddresses = sendFailedException.getInvalidAddresses();
            return Arrays.stream(invalidAddresses).map(Address::toString).collect(Collectors.toList());
        }
        // 发送成功
        return new ArrayList<>();
    }
}